import Foundation
import CoreLocation

// MARK: - 基础枚举定义
enum ElderlyCareServiceType: String, Codable, CaseIterable {
    case nursingHome        = "养老院住宿"
    case dayCare            = "日间照料"
    case homeNursing        = "上门护理"
    case homeBathing        = "上门助浴"
    case homeRehabilitation = "上门康复"
    case hospitalEscort     = "医院陪诊"
    case ecoTherapy         = "自然生态疗法"
    case culturalCompanion  = "文化陪伴"
    case digitalCompanion   = "数字陪伴"
    
    var iconName: String {
        switch self {
        case .nursingHome: return "house.fill"
        case .dayCare: return "sun.max.fill"
        case .homeNursing: return "cross.case.fill"
        case .homeBathing: return "drop.fill"
        case .homeRehabilitation: return "figure.walk"
        case .hospitalEscort: return "cross.fill"
        case .ecoTherapy: return "leaf.fill"
        case .culturalCompanion: return "book.fill"
        case .digitalCompanion: return "iphone"
        }
    }
}

enum UrgencyLevel: String, Codable, CaseIterable {
    case low = "低"
    case medium = "中"
    case high = "高"
    
    var priority: Int {
        switch self {
        case .low: return 1
        case .medium: return 2
        case .high: return 3
        }
    }
}

enum DemandStatus: String, Codable {
    case pending = "待匹配"
    case matched = "已匹配"
    case inProgress = "进行中"
    case completed = "已完成"
    case cancelled = "已取消"
}

// MARK: - 生态评分模型
struct EcoScores: Codable, Equatable {
    let environmental: Double  // 环境友好度 (0-100)
    let social: Double         // 社会责任度 (0-100)
    let economic: Double       // 经济可持续性 (0-100)
    
    var average: Double {
        return (environmental + social + economic) / 3
    }
    
    static let zero = EcoScores(environmental: 0, social: 0, economic: 0)
}

// MARK: - 服务提供者模型
struct CareProvider: Codable, Identifiable, Hashable {
    let id: UUID
    let name: String
    let type: ElderlyCareServiceType
    let location: CLLocationCoordinate2D
    let capacity: Int
    let availableTime: [TimeInterval]
    let rating: Double
    let certifications: [String]
    let ecoScores: EcoScores
    let hourlyRate: Double?
    let description: String
    
    // 计算与某位置的距离（单位：公里）
    func distance(from location: CLLocationCoordinate2D) -> Double {
        let coordinate1 = CLLocation(latitude: self.location.latitude, longitude: self.location.longitude)
        let coordinate2 = CLLocation(latitude: location.latitude, longitude: location.longitude)
        return coordinate1.distance(from: coordinate2) / 1000 // 转换为公里
    }
    
    // 检查在指定时间是否可用
    func isAvailable(at time: TimeInterval) -> Bool {
        let hour = Int(time) % 24
        return availableTime.contains { interval in
            let startHour = Int(interval) % 24
            let endHour = Int(interval + 8) % 24 // 假设8小时工作制
            return hour >= startHour && hour < endHour
        }
    }
}

// MARK: - 老人需求模型
struct ElderlyDemand: Codable, Identifiable {
    let id: UUID
    let elderId: String
    let type: ElderlyCareServiceType
    let urgency: UrgencyLevel
    let location: CLLocationCoordinate2D
    let startTime: TimeInterval
    let endTime: TimeInterval?
    let specialRequirements: [String]
    let preferredEcoScores: EcoScores?
    var matchedProvider: CareProvider?
    var status: DemandStatus
    let createdAt: Date
    let budget: Double?
    
    // 计算需求持续时间（小时）
    var duration: Double {
        let end = endTime ?? startTime + 3600 // 默认1小时
        return (end - startTime) / 3600
    }
    
    // 计算匹配分数
    func calculateMatchScore(with provider: CareProvider) -> Double {
        var score = 0.0
        
        // 服务类型匹配
        if provider.type == type {
            score += 100
        }
        
        // 距离因素（越近越好）
        let distance = provider.distance(from: location)
        let distanceScore = max(0, 100 - distance * 2)
        score += distanceScore
        
        // 评分因素
        score += provider.rating * 20
        
        // 生态评分因素
        if let preferred = preferredEcoScores {
            let ecoDiff = abs(provider.ecoScores.average - preferred.average)
            score += max(0, 50 - ecoDiff)
        } else {
            score += provider.ecoScores.average * 0.5
        }
        
        // 紧急程度权重
        score *= Double(urgency.priority)
        
        return score
    }
}

// MARK: - 调度规则模型
struct DispatchRule: Codable {
    let regionId: String
    let serviceTypeWeights: [ElderlyCareServiceType: Double]
    let priorityFactors: [PriorityFactor: Double]
    let maxDistance: Double // 最大服务距离（公里）
    let ecoWeight: Double   // 生态评分权重
}

enum PriorityFactor: String, Codable {
    case distance
    case rating
    case urgency
    case ecoScore
    case capacity
}

// MARK: - 调度系统核心
class ElderlyCareDispatchSystem {
    private var providers: [CareProvider] = []
    private var demands: [ElderlyDemand] = []
    private var dispatchRules: [String: DispatchRule] = [:]
    
    // 添加服务提供者
    func addProvider(_ provider: CareProvider) {
        providers.append(provider)
    }
    
    // 添加需求
    func addDemand(_ demand: ElderlyDemand) {
        demands.append(demand)
    }
    
    // 设置调度规则
    func setDispatchRule(_ rule: DispatchRule) {
        dispatchRules[rule.regionId] = rule
    }
    
    // 智能匹配算法
    func matchDemand(_ demand: ElderlyDemand) -> CareProvider? {
        let regionId = getRegionId(for: demand.location)
        let rule = dispatchRules[regionId] ?? createDefaultRule()
        
        // 过滤可用的服务提供者
        let availableProviders = providers.filter { provider in
            provider.type == demand.type &&
            provider.distance(from: demand.location) <= rule.maxDistance &&
            provider.capacity > 0 &&
            provider.isAvailable(at: demand.startTime)
        }
        
        guard !availableProviders.isEmpty else { return nil }
        
        // 计算匹配分数并排序
        let scoredProviders = availableProviders.map { provider in
            (provider: provider, score: calculateMatchScore(demand: demand, provider: provider, rule: rule))
        }.sorted { $0.score > $1.score }
        
        return scoredProviders.first?.provider
    }
    
    // 批量匹配所有待处理需求
    func processAllPendingDemands() -> [(demand: ElderlyDemand, provider: CareProvider)] {
        var matches: [(ElderlyDemand, CareProvider)] = []
        
        for index in demands.indices where demands[index].status == .pending {
            if let provider = matchDemand(demands[index]) {
                demands[index].matchedProvider = provider
                demands[index].status = .matched
                matches.append((demands[index], provider))
            }
        }
        
        return matches
    }
    
    // 计算匹配分数
    private func calculateMatchScore(demand: ElderlyDemand, provider: CareProvider, rule: DispatchRule) -> Double {
        var score = 0.0
        
        // 基础权重
        let serviceWeight = rule.serviceTypeWeights[demand.type] ?? 1.0
        score += serviceWeight * 100
        
        // 距离因素
        let distance = provider.distance(from: demand.location)
        let distanceWeight = rule.priorityFactors[.distance] ?? 0.3
        score += (1 - min(distance / rule.maxDistance, 1)) * 100 * distanceWeight
        
        // 评分因素
        let ratingWeight = rule.priorityFactors[.rating] ?? 0.2
        score += (provider.rating / 5.0) * 100 * ratingWeight
        
        // 紧急程度
        let urgencyWeight = rule.priorityFactors[.urgency] ?? 0.3
        score += Double(demand.urgency.priority) * 100 * urgencyWeight
        
        // 生态评分
        let ecoWeight = rule.ecoWeight
        score += (provider.ecoScores.average / 100.0) * 100 * ecoWeight
        
        return score
    }
    
    // 获取区域ID（简化版本）
    private func getRegionId(for location: CLLocationCoordinate2D) -> String {
        // 这里应该根据实际地理位置返回区域ID
        // 简化实现：根据经纬度划分区域
        let latZone = Int(location.latitude * 10)
        let lonZone = Int(location.longitude * 10)
        return "REGION_\(latZone)_\(lonZone)"
    }
    
    private func createDefaultRule() -> DispatchRule {
        return DispatchRule(
            regionId: "DEFAULT",
            serviceTypeWeights: Dictionary(uniqueKeysWithValues: ElderlyCareServiceType.allCases.map { ($0, 1.0) }),
            priorityFactors: [
                .distance: 0.3,
                .rating: 0.2,
                .urgency: 0.3,
                .ecoScore: 0.1,
                .capacity: 0.1
            ],
            maxDistance: 50.0,
            ecoWeight: 0.2
        )
    }
    
    // 获取统计信息
    func getStatistics() -> (totalProviders: Int, totalDemands: Int, pendingDemands: Int, matchedDemands: Int) {
        let pending = demands.filter { $0.status == .pending }.count
        let matched = demands.filter { $0.status == .matched || $0.status == .inProgress }.count
        return (providers.count, demands.count, pending, matched)
    }
}

// MARK: - 示例数据和测试
extension ElderlyCareDispatchSystem {
    func loadSampleData() {
        // 添加示例服务提供者
        let providers = [
            CareProvider(
                id: UUID(),
                name: "阳光养老院",
                type: .nursingHome,
                location: CLLocationCoordinate2D(latitude: 39.9042, longitude: 116.4074),
                capacity: 100,
                availableTime: [32400, 43200, 54000], // 9:00, 12:00, 15:00
                rating: 4.5,
                certifications: ["养老护理员证", "医疗机构执业许可证"],
                ecoScores: EcoScores(environmental: 85, social: 90, economic: 75),
                hourlyRate: 150.0,
                description: "提供24小时专业护理服务，环境优美，设施齐全"
            ),
            CareProvider(
                id: UUID(),
                name: "爱心护理中心",
                type: .homeNursing,
                location: CLLocationCoordinate2D(latitude: 39.9142, longitude: 116.4174),
                capacity: 20,
                availableTime: [28800, 36000, 43200], // 8:00, 10:00, 12:00
                rating: 4.8,
                certifications: ["护士执业证", "养老护理员证"],
                ecoScores: EcoScores(environmental: 90, social: 85, economic: 80),
                hourlyRate: 200.0,
                description: "专业护士上门提供护理服务，个性化护理方案"
            ),
            CareProvider(
                id: UUID(),
                name: "康复之家",
                type: .homeRehabilitation,
                location: CLLocationCoordinate2D(latitude: 39.9242, longitude: 116.4274),
                capacity: 15,
                availableTime: [32400, 39600, 46800], // 9:00, 11:00, 13:00
                rating: 4.6,
                certifications: ["康复治疗师证", "医师执业证"],
                ecoScores: EcoScores(environmental: 80, social: 88, economic: 85),
                hourlyRate: 180.0,
                description: "专业康复师上门指导康复训练，科学有效"
            )
        ]
        
        providers.forEach { addProvider($0) }
        
        // 添加示例需求
        let demands = [
            ElderlyDemand(
                id: UUID(),
                elderId: "ELDER_001",
                type: .homeNursing,
                urgency: .high,
                location: CLLocationCoordinate2D(latitude: 39.9150, longitude: 116.4180),
                startTime: Date().timeIntervalSince1970 + 3600,
                endTime: Date().timeIntervalSince1970 + 7200,
                specialRequirements: ["糖尿病护理", "需要轮椅"],
                preferredEcoScores: EcoScores(environmental: 80, social: 85, economic: 75),
                matchedProvider: nil,
                status: .pending,
                createdAt: Date(),
                budget: 300.0
            ),
            ElderlyDemand(
                id: UUID(),
                elderId: "ELDER_002",
                type: .nursingHome,
                urgency: .medium,
                location: CLLocationCoordinate2D(latitude: 39.9050, longitude: 116.4080),
                startTime: Date().timeIntervalSince1970 + 86400,
                endTime: nil,
                specialRequirements: ["素食", "需要单人间"],
                preferredEcoScores: nil,
                matchedProvider: nil,
                status: .pending,
                createdAt: Date(),
                budget: 5000.0
            )
        ]
        
        demands.forEach { addDemand($0) }
    }
}

// MARK: - 命令行测试接口
func runTests() {
    print("🚀 启动老年人护理服务调度系统测试...")
    
    let system = ElderlyCareDispatchSystem()
    system.loadSampleData()
    
    let stats = system.getStatistics()
    print("📊 系统统计：")
    print("   服务提供者：\(stats.totalProviders)")
    print("   总需求：\(stats.totalDemands)")
    print("   待匹配：\(stats.pendingDemands)")
    print("   已匹配：\(stats.matchedDemands)")
    
    print("\n🔍 开始智能匹配...")
    let matches = system.processAllPendingDemands()
    
    for (demand, provider) in matches {
        print("✅ 匹配成功：")
        print("   需求：\(demand.type.rawValue) - \(demand.specialRequirements.joined(separator: ", "))")
        print("   匹配到：\(provider.name)")
        print("   距离：\(String(format: "%.2f", provider.distance(from: demand.location))) 公里")
        print("   费用：¥\(demand.budget ?? 0) / 小时")
    }
    
    let newStats = system.getStatistics()
    print("\n📈 匹配完成：")
    print("   成功匹配：\(matches.count) 个需求")
    print("   剩余待匹配：\(newStats.pendingDemands) 个需求")
}

// 运行测试
runTests()